<script setup>
import { ref, onMounted, computed, onUpdated } from 'vue'
import { useUserStore } from '@/store'

// 判断是否已经连接上netty服务器
const isLogin = ref(false)
// 聊天页面盒子高度
const mgsBoxHeight = ref(0)
const msgBox = ref(null)
onMounted(() => {
    mgsBoxHeight.value = window.innerHeight - 100
    msgBox.value = document.querySelector('.msgBox')
})
onUpdated(() => {
    // 将滚动条保持在底部
    msgBox.value.scrollTop = msgBox.value.scrollHeight
})
// 在线用户列表
const userList = ref([])
// 选择的私聊对象(默认全体聊天)
const userActive = ref('all')
// 发送消息类型
const sendType = computed(() => userActive.value === 'all' ? 2 : 1)
// 消息接收人
const sendTarget = computed(() => sendType.value === 1 ? userActive.value : '')
// 要发送的消息内容
const msgContent = ref('')
// 收到的所有消息列表
const messageList = ref([])
// 全部的消息
const allMessage = computed(() => messageList.value.filter(item => item.type === 2))
// 获取对应用户的私聊消息
const userMessage = computed(() => messageList.value.filter(item => item.type === 1 && item.name === userActive.value))

const userStore = useUserStore()

const userInfo = userStore.userInfo

const websocket = new WebSocket('ws://localhost:8081/ws')

websocket.onopen = e => {
    // 如果没有连接就发送连接请求
    if (!isLogin.value) {
        isLogin.value = true
        const message = {
            code: 10001, // 连接
            name: userInfo.name // 用户账号
        }
        // 发送连接请求
        websocket.send(JSON.stringify(message))
    }
    console.log('websocket连接成功')
}

const matchArrUser = str => {
    const start = str.indexOf('[')
    const end = str.indexOf(']')
    str = str.substring(start + 1, end)
    return str.split(',').map(item => item.trim()) || []
}

websocket.onmessage = e => {
    const data = JSON.parse(e.data) // 解析收到的消息
    if (data.name === '系统消息') {
        // 排除掉自己
        userList.value = matchArrUser(data.msg).filter(item => item !== userInfo.name)
    } else {
        let type // 消息类型 1 私聊 2 是群发
        let name = data.name
        if (name.endsWith('群发')) {
            name = name.substring(0, name.indexOf('群发'))
            type = 2
        } else {
            type = 1
        }
        // 添加消息到消息列表
        messageList.value.push({
            type, // 消息类型 1 私聊 2 是群发
            name, // 消息名称
            msg: data.msg, // 消息内容
            time: data.time // 消息时间
        })
    }

}

websocket.onclose = e => {
    console.log('websocket连接关闭', e)
}

websocket.onerror = e => {
    console.log('websocket连接错误', e)
}

// 选择私聊对象
const selectUser = user => userActive.value = user

// 发送消息
const send = () => {
    if (!msgContent.value) {
        ElMessage({
            message: '不能发送空消息',
            type: 'warning',
        })
        return
    }
    // 判断是发群消息还是私聊消息
    const message = {
        code: 10002, // 发送消息
        type: sendType.value, // 消息类型 1 私聊 2 群聊
        target: sendTarget.value, // 接收消息的人
        name: userInfo.name, // 用户昵称(自己的名字)
        content: msgContent.value // 消息内容  
    }
    // 如果是私聊要把自己消息添加到私聊列表中
    if (sendType.value === 1) {
        // 添加消息到消息列表
        messageList.value.push({
            isMe: true, // 是否是本人发送的消息
            type: 1, // 消息类型 1 私聊 2 是群发
            name: sendTarget.value, // 消息名称
            msg: msgContent.value, // 消息内容
            time: new Date().toLocaleDateString() // 消息时间
        })
    }
    websocket.send(JSON.stringify(message))
    // 发送完后清空输入框
    msgContent.value = ''
}
</script>

<template>
    <div flex w-full p-0 :style="{ height: mgsBoxHeight + 'px' }" style="border: 1px solid #ccc; border-radius: 4px;">
        <div class="w-1/4" h-full style="overflow-y: scroll; border-right: 1px solid #ccc;">
            <div @click="selectUser('all')" :class="{ active: userActive === 'all' }" class="item">
                全体聊天
            </div>
            <div @click="selectUser(user)" :class="{ active: userActive === user }" class="item" v-for="user in userList"
                :key="user">
                {{ user }}
            </div>
        </div>
        <div class="chatBox">
            <div class="msgBox">
                <!-- 全体消息 -->
                <template v-if="sendType === 2">
                    <div class="msgItem" :class="{ active: msg.name === userInfo.name }" v-for="(msg, index) in allMessage"
                        :key="index">
                        <span text-2xl mb-1>{{ msg.name }}</span>
                        <div>{{ msg.msg }}</div>
                    </div>
                </template>
                <!-- 私聊消息 -->
                <template v-else>
                    <div class="msgItem" :class="{ active: msg.isMe }" v-for="(msg, index) in userMessage" :key="index">
                        <span text-2xl mb-1>{{ msg.name }}</span>
                        <div>{{ msg.msg }}</div>
                    </div>
                </template>
            </div>
            <div flex>
                <el-input class="mr-1" v-model="msgContent" placeholder="输入要发送的消息"></el-input>
                <el-button type="primary" @click="send">发送</el-button>
            </div>
        </div>
    </div>
</template>

<style scoped>
.item {
    color: #409eff;
    border-bottom: 1px solid #67c23a;
    text-align: center;
    height: 60px;
    line-height: 60px;
    user-select: none;
    cursor: pointer;
    transition: all 0.3s;
}

.item.active {
    background-color: #409eff;
    color: #fff;
}

.chatBox {
    flex: 1;
    padding: 10px;
    height: 100%;
}

.msgBox {
    margin-bottom: 10px;
    height: calc(100% - 60px);
    overflow-y: scroll;
}

.msgItem {
    padding: 10px 5px;
    margin-bottom: 10px;
    background-color: #409eff;
    color: #fff;
    font-size: 16px;
    border-radius: 6px;
}

.msgItem.active {
    background-color: #67c23a;
}
</style>